package com.naiterui.ehp.bs.doctor.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.base.Splitter;
import com.naiterui.ehp.bp.bo.consult.SuperviseVideoBO;
import com.naiterui.ehp.bp.bo.consult.SuperviseVideoInfoBO;
import com.naiterui.ehp.bp.bo.consult.VideoConsultBO;
import com.naiterui.ehp.bp.bo.emr.InquireCaseBO;
import com.naiterui.ehp.bp.bo.im.SessionDetailBO;
import com.naiterui.ehp.bp.bo.patient.PatientInquirerBO;
import com.naiterui.ehp.bp.bo.recommend.SuperviseDiagnosisBO;
import com.naiterui.ehp.bp.constants.SuperviseConstant;
import com.naiterui.ehp.bp.domain.ConsultSession;
import com.naiterui.ehp.bp.domain.Department;
import com.naiterui.ehp.bp.domain.Doctor;
import com.naiterui.ehp.bp.domain.DrAccountOperateLog;
import com.naiterui.ehp.bp.domain.DrConsultComment;
import com.naiterui.ehp.bp.domain.DrMessageConsultOrder;
import com.naiterui.ehp.bp.domain.DrVideoConsult;
import com.naiterui.ehp.bp.domain.Hospital;
import com.naiterui.ehp.bp.domain.Licence;
import com.naiterui.ehp.bp.domain.Patient;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bs.doctor.domain.RecordUserInfo;
import com.naiterui.ehp.bs.doctor.fegin.EmrFeignClient;
import com.naiterui.ehp.bs.doctor.fegin.ImFeginClient;
import com.naiterui.ehp.bs.doctor.fegin.PatientFeignClient;
import com.naiterui.ehp.bs.doctor.fegin.RecomFeginClient;
import com.naiterui.ehp.bs.doctor.fegin.VideoConsultFeignClient;
import com.naiterui.ehp.bs.doctor.repository.IConsultSessionRepository;
import com.naiterui.ehp.bs.doctor.repository.IDepartmentRepository;
import com.naiterui.ehp.bs.doctor.repository.IDoctorRepository;
import com.naiterui.ehp.bs.doctor.repository.IDrAccountOperateLogRepository;
import com.naiterui.ehp.bs.doctor.repository.IDrConsultCommentRepository;
import com.naiterui.ehp.bs.doctor.repository.IDrMessageConsultOrderRepository;
import com.naiterui.ehp.bs.doctor.repository.IHospitalRepository;
import com.naiterui.ehp.bs.doctor.repository.ILicenceRepository;
import com.naiterui.ehp.bs.doctor.repository.IPatientRepository;
import com.naiterui.ehp.bs.doctor.repository.IRecordUserInfoRepository;
import com.naiterui.ehp.bs.doctor.service.ISuperviseService;
import com.naiterui.ehp.bs.doctor.vo.LicenceVO;
import com.naiterui.ehp.bs.doctor.vo.PrescriptionVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseConsultCommentVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseDepartmentVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseDiagnosisVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseDoctorRecordVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseDoctorVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseFirstToDoctorVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseMedicalRecordVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseRecomVO;
import com.naiterui.ehp.bs.doctor.vo.SuperviseSessionVO;
import com.naiterui.ehp.bs.doctor.vo.TianjinSuperviseSessionVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <pre>
 *
 * </pre>
 *
 * @author fangguanhong
 * @date 2021/1/13 下午10:00
 * @since 1.0.0
 */
@Service
public class AdSuperviseServiceImpl implements ISuperviseService {

    @Autowired
    private IConsultSessionRepository consultSessionRepository;
    @Autowired
    private IPatientRepository patientRepository;
    @Autowired
    private IDoctorRepository doctorRepository;
    @Autowired
    private IDepartmentRepository departmentRepository;
    @Autowired
    private RecomFeginClient recomFeginClient;
    @Autowired
    private IDrConsultCommentRepository consultCommentRepository;
    @Autowired
    private EmrFeignClient emrFeignClient;
    @Autowired
    private IDrAccountOperateLogRepository accountOperateLogRepository;
    @Autowired
    private ILicenceRepository licenceRepository;
    @Autowired
    private IRecordUserInfoRepository recordUserInfoRepository;
    @Autowired
    private IHospitalRepository hospitalRepository;
    @Autowired
    private IDrMessageConsultOrderRepository messageConsultOrderRepository;
    @Autowired
    private ImFeginClient imFeginClient;
    @Autowired
    private PatientFeignClient patientFeignClient;
    @Autowired
    private VideoConsultFeignClient videoConsultFeignClient;

    private String IMG_DOMAIN = ConfigUtil.getString("ehp.domain.img");

    /**
     * 查询给定时间范围或者昨天0-24点之间结束的会话相关信息
     * 包含：会话、处方、诊断、病历
     *
     * @return
     */
    @Override
    public List<SuperviseSessionVO> getSessions(List<String> sesIds) {
        List<SuperviseSessionVO> result = new ArrayList<>();
        /*Date startD = null;
        Date endD = null;
        // 会话信息
        if (StringUtils.isNotEmpty(start) && StringUtils.isNotEmpty(end)) {
            startD = DateUtil.parseStrToCustomPatternDate(start, DateUtil.DATE_TIME_FORMAT);
            endD = DateUtil.parseStrToCustomPatternDate(end, DateUtil.DATE_TIME_FORMAT);
        } else {
            // 取昨天数据
            String date = DateTimeFormatter.ofPattern("yyyy-MM-dd")
                                           .withZone(ZoneId.systemDefault()).format(Instant.now().minus(1, ChronoUnit.DAYS));
            startD = DateUtil.parseStrToCustomPatternDate(date + " 00:00:00", DateUtil.DATE_TIME_FORMAT);
            endD = DateUtil.parseStrToCustomPatternDate(date + " 23:59:59", DateUtil.DATE_TIME_FORMAT);
        }*/
        List<ConsultSession> consultSessions = consultSessionRepository.findBySessionIdIn(sesIds);

        if (CollectionUtil.isNotEmpty(consultSessions)) {
            // mysql会话ID列表
            List<Long> sessionIds = consultSessions.stream().map(ses -> ses.getId()).collect(Collectors.toList());
            List<DrMessageConsultOrder> consultOrders = messageConsultOrderRepository.findByConsultSessionIdIn(sessionIds);
            Map<Long, DrMessageConsultOrder> consultOrderMap =
                    consultOrders.stream().collect(Collectors.toMap(DrMessageConsultOrder::getConsultSessionId, e -> e));
            // 医生ID列表
            List<Long> doctorIds = consultSessions.stream().map(session -> session.getDoctorId()).collect(Collectors.toList());
            List<Licence> licenceList = licenceRepository.findByTypeAndDoctorIdIn(Licence.DOCTOR_LICENCE_TYPE_QUALIFICATION_CERTIFICATE, doctorIds);
            Map<Long, List<Licence>> licenceMap = licenceList.stream().collect(Collectors.groupingBy(Licence::getDoctorId));

            for (ConsultSession session : consultSessions) {
                Long patientId = session.getPatientId();
                Long doctorId = session.getDoctorId();
                Patient patient = patientRepository.get(patientId);
                Doctor doctor = doctorRepository.get(doctorId);
                if (doctor.getType().equals(Doctor.TYPE_TEST)) {
                    continue;
                }
                Department department = departmentRepository.get(doctor.getDepartmentId());
                DrConsultComment consultComment = consultCommentRepository.findFirstByConsultSessionId(session.getId());
                DrMessageConsultOrder consultOrder = consultOrderMap.get(session.getId());
                List<Licence> licences = licenceMap.get(session.getDoctorId());
                SuperviseSessionVO vo = SuperviseSessionVO.builder()
                    .sessionId(session.getSessionId())
                    .startTime(DateUtil.parseDateToString(session.getStartTime(),
                        DateUtil.DATE_TIME_FORMAT))
                    .departmentCode(department.getCode())
                    .departmentName(department.getName())
                    .patientId(patientId)
                    .doctorId(doctorId)
                    .patientName(patient.getName())
                    .patientGender(patient.getGender())
                    .patientBirthday(DateUtil.parseDateToString(patient.getBirthday(),
                        DateUtil.DATE_TIME_FORMAT))
                    .patientAge(patient.getAge())
                    .doctorName(doctor.getName())
                    .serviceEndTime(DateUtil.parseDateToString(session.getEndTime(),
                        DateUtil.DATE_TIME_FORMAT))
                    .patientSatisfaction(null != consultComment ? consultComment.getStarLevel() : 3)
                    .patientIdCardNo(patient.getIdCard())
                    .doctorLicenseNo(CollectionUtil.isNotEmpty(licences) ? licences.get(0).getNumber() : null)
                    .hasReply(1)
                    .build();
                // 处方信息
                List<SuperviseRecomVO> recomVOS = recomFeginClient.sessionRecoms(session.getId());
                vo.setRecommends(recomVOS);
                // 病历信息
                List<SuperviseMedicalRecordVO> medicalRecordVOS = emrFeignClient.medicalRecord(session.getSessionId(), session.getPatientId(),
                    session.getDoctorId());
                // 病情描述信息
                SuperviseFirstToDoctorVO firstToDoctor = emrFeignClient.firseToDoctor(session.getPatientId());
                if (null != firstToDoctor) {
                    vo.setFirstDescription(firstToDoctor.getFirstDescription());
                    vo.setFirstHospitalCode(firstToDoctor.getFirstHospitalCode());
                    vo.setFirstHospitalName(firstToDoctor.getFirstHospitalName());
                }
                // 病历信息根据诊断名称补充诊断编码
                if (CollectionUtil.isNotEmpty(medicalRecordVOS)) {
                    medicalRecordVOS.forEach(medicalRecord -> {
                        List<SuperviseDiagnosisVO> recordInfo = new ArrayList<>();
                        List<SuperviseDiagnosisVO> diagnosisVOS = medicalRecord.getDiagnosis();
                        List<String> names = diagnosisVOS.stream().map(diagnosisVO -> diagnosisVO.getName()).collect(Collectors.toList());
                        List<SuperviseDiagnosisBO> boList = recomFeginClient.diagnosiss(names);
                        medicalRecord.setDiagnosis(boList.stream()
                            .map(bo -> SuperviseDiagnosisVO.builder()
                                .id(bo.getId())
                                .name(bo.getName())
                                .code(bo.getCode())
                                .build())
                            .collect(Collectors.toList()));
                    });
                }

                vo.setMedicalRecords(medicalRecordVOS);
                if (null != consultOrder) {
                    // 问诊价格
                    vo.setPrice(consultOrder.getPrice());
                    vo.setOrderSn(consultOrder.getOrderSn());
                    vo.setPayTime(null != consultOrder.getChangedAt() ? DateUtil.parseDateToString(consultOrder.getChangedAt(),
                        DateUtil.DATE_TIME_FORMAT) : null);
                    vo.setPayTag(DrMessageConsultOrder.CONSULT_ORDER_PAY_STATUS_YES == consultOrder.getPayStatus().intValue() ?
                        DrMessageConsultOrder.MESSAGE_PAY_STATUS_YES : DrMessageConsultOrder.MESSAGE_PAY_STATUS_NO);
                    vo.setPayOrderId(consultOrder.getId());
                }
                result.add(vo);
            }
        }
        return result;
    }

    @Override
    public List<SuperviseDoctorVO> doctorList(String start, String end, Long doctorId) {
        List<SuperviseDoctorVO> result = new ArrayList<>();
        List<Long> doctorIds;
        if (doctorId == null) {
            Date startD = null;
            Date endD = null;
            if (StringUtils.isNotEmpty(start) && StringUtils.isNotEmpty(end)) {
                startD = DateUtil.parseStrToCustomPatternDate(start, DateUtil.DATE_TIME_FORMAT);
                endD = DateUtil.parseStrToCustomPatternDate(end, DateUtil.DATE_TIME_FORMAT);
            } else {
                // 查找昨天的数据
                // 取昨天数据
                String date = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.systemDefault())
                    .format(Instant.now().minus(1, ChronoUnit.DAYS));
                startD = DateUtil.parseStrToCustomPatternDate(date + " 00:00:00", DateUtil.DATE_TIME_FORMAT);
                endD = DateUtil.parseStrToCustomPatternDate(date + " 23:59:59", DateUtil.DATE_TIME_FORMAT);
            }
            // 规定时间范围内的备案审核通过的医生
            List<DrAccountOperateLog> operateLogs =
                accountOperateLogRepository.findByStatusAndCreatedAtBetween(Doctor.RECORD_STATUS_SUCCESS, startD, endD);
            // 需要同步的医生ID
            doctorIds = operateLogs.stream().map(log -> log.getDoctorId()).collect(Collectors.toList());
        } else {
            doctorIds = Arrays.asList(doctorId);
        }
        if (CollectionUtils.isEmpty(doctorIds)) {
            return null;
        }
        List<Doctor> doctors = doctorRepository.findByIdIn(doctorIds);
        if (CollectionUtil.isNotEmpty(doctors)) {
            // 需要同步的医生ID
            List<Licence> licences = licenceRepository.findByDoctorIdIn(doctorIds);
            // 根据医生ID分组
            Map<Long, List<Licence>> doctorLicenceMap = licences.stream().collect(Collectors.groupingBy(Licence::getDoctorId));
            if (CollectionUtil.isNotEmpty(doctors)) {
                doctors.forEach(doctor -> {
                    Department department = departmentRepository.get(doctor.getDepartmentId());
                    RecordUserInfo recordUserInfo = recordUserInfoRepository.findByUserIdAndUserType(doctor.getId(), RecordUserInfo.USER_TYPE_DR);
                    List<Licence> doctorLicence = doctorLicenceMap.get(doctor.getId());
                    Hospital hospital = hospitalRepository.get(doctor.getHospitalId());
                    // 类型分组
                    Map<Integer, Licence> licenceMap = doctorLicence.stream().collect(Collectors.toMap(Licence::getType, e -> e));
                    SuperviseDoctorVO vo = SuperviseDoctorVO.builder().id(doctor.getId()).name(doctor.getName())
                        .gender(doctor.getGender()).birthday(null)
                        .idCard(licenceMap.get(Licence.DOCTOR_LICENCE_TYPE_IDCARD).getNumber()).departmentCode(null)
                        .departmentId(department.getId())
                        .departmentName(department.getName()).title(doctor.getTitleId().toString())
                        .phone(doctor.getPhone()).expertise(doctor.getExpertise())
                        .createdAt(DateUtil.parseDateToString(doctor.getCreatedAt(), DateUtil.DATE_TIME_FORMAT))
                        .headUrl(IMG_DOMAIN + doctor.getHeadUrl()).workHospitalId(hospital.getId())
                        .workHospitalName(hospital.getName()).tag(SuperviseDoctorVO.TAG_ADD)
                        .medical(buildLicenceVo(licenceMap.get(Licence.DOCTOR_LICENCE_TYPE_MEDICAL)))
                        .qualificationCertificate(
                            buildLicenceVo(licenceMap.get(Licence.DOCTOR_LICENCE_TYPE_QUALIFICATION_CERTIFICATE)))
                        .build();
                    if (null != recordUserInfo) {
                        vo.setNational(recordUserInfo.getNationName());
                        vo.setWorkDate(DateUtil.parseDateToString(recordUserInfo.getPracStartDate(), DateUtil.DATE_TIME_FORMAT));
                        vo.setWorkHospitalCode(recordUserInfo.getHospitalCode());
                        vo.setCertIssue(recordUserInfo.getCertIssue());
                        vo.setPracIssue(recordUserInfo.getPracIssue());
                    }
                    result.add(vo);
                });
            }
        }
        return result;
    }

    private LicenceVO buildLicenceVo(Licence licence) {
        if (licence == null) {
            return null;
        }
        List<String> urls = Splitter.on(',').splitToList(Optional.ofNullable(licence.getUrl()).orElse(""));
        List<String> urlInfo = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(urls)) {
            urls.forEach(url -> {
                urlInfo.add(IMG_DOMAIN + url);
            });
        }
        return new LicenceVO(licence.getDoctorId(), licence.getType(), licence.getNumber(), urlInfo);
    }

    @Override
    public PrescriptionVO getPrescription(String sessionId) {
        ConsultSession consultSession = consultSessionRepository.findFirstBySessionId(sessionId);
        if (null != consultSession) {
            return recomFeginClient.getPrescription(consultSession.getId());
        }
        return null;
    }

    @Override
    public List<SuperviseDepartmentVO> getDepartmentList(String start, String end) {
        List<SuperviseDepartmentVO> result = new ArrayList<>();
        Date startD = null;
        Date endD = null;
        // 会话信息
        if (StringUtils.isNotEmpty(start) && StringUtils.isNotEmpty(end)) {
            startD = DateUtil.parseStrToCustomPatternDate(start, DateUtil.DATE_TIME_FORMAT);
            endD = DateUtil.parseStrToCustomPatternDate(end, DateUtil.DATE_TIME_FORMAT);
        } else {
            // 取昨天数据
            String date = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.systemDefault())
                .format(Instant.now().minus(1, ChronoUnit.DAYS));
            startD = DateUtil.parseStrToCustomPatternDate(date + " 00:00:00", DateUtil.DATE_TIME_FORMAT);
            endD = DateUtil.parseStrToCustomPatternDate(date + " 23:59:59", DateUtil.DATE_TIME_FORMAT);
        }

        List<Department> departments = departmentRepository.findByAvailableAndCreatedAtBetween(true, startD, endD);
        if (CollectionUtil.isNotEmpty(departments)) {
            departments.forEach(department -> {
                SuperviseDepartmentVO vo = SuperviseDepartmentVO.builder().id(department.getId())
                    .name(department.getName()).code(department.getCode()).introduction(null)
                    .createdAt(DateUtil.parseDateToString(department.getCreatedAt(), DateUtil.DATE_TIME_FORMAT))
                    .build();
                result.add(vo);
            });
        }
        return result;
    }

    @Override
    public List<SuperviseDoctorRecordVO> doctorRecordList(Date startDate, Date endDate, Long doctorId) {
        List<Long> doctorIds;
        if (doctorId == null) {
            // 规定时间范围内的备案审核通过的医生
            List<DrAccountOperateLog> operateLogs = accountOperateLogRepository
                .findByStatusAndCreatedAtBetween(Doctor.RECORD_STATUS_SUCCESS, startDate, endDate);
            if (CollectionUtils.isEmpty(operateLogs)) {
                return null;
            }
            // 需要同步的医生ID
            doctorIds = operateLogs.stream().map(log -> log.getDoctorId()).collect(Collectors.toList());
        } else {
            doctorIds = Arrays.asList(doctorId);
        }
        List<Doctor> doctors = doctorRepository.findByIdIn(doctorIds);
        List<Licence> licences = licenceRepository.findByDoctorIdIn(doctorIds);
        // 根据医生ID分组
        Map<Long, List<Licence>> doctorLicenceMap =
            licences.stream().collect(Collectors.groupingBy(Licence::getDoctorId));
        List<SuperviseDoctorRecordVO> result = new ArrayList();
        if (CollectionUtil.isNotEmpty(doctors)) {
            doctors.forEach(doctor -> {
                List<Licence> doctorLicence = doctorLicenceMap.get(doctor.getId());
                // 类型分组
                Map<Integer, Licence> licenceMap =
                    doctorLicence.stream().collect(Collectors.toMap(Licence::getType, e -> e));
                result.add(SuperviseDoctorRecordVO.builder().id(doctor.getId()).name(doctor.getName())
                    .idCard(licenceMap.get(Licence.DOCTOR_LICENCE_TYPE_IDCARD).getNumber()).build());
            });
        }
        return result;
    }

    @Override
    public List<TianjinSuperviseSessionVO> tianjinSessions(String start, String end) throws BusinessException {
        Date startD = DateUtil.parseStrToCustomPatternDate(start, DateUtil.DATE_TIME_FORMAT);
        Date endD = DateUtil.parseStrToCustomPatternDate(end, DateUtil.DATE_TIME_FORMAT);
        List<ConsultSession> consultSessions =
            consultSessionRepository.findByEndTimeBetweenAndEndTimeIsNotNull(startD, endD);
        List<TianjinSuperviseSessionVO> result = generateTianjinSuperviseSession(consultSessions);

        return result;
    }

    public List<TianjinSuperviseSessionVO> generateTianjinSuperviseSession(List<ConsultSession> consultSessions)
        throws BusinessException {
        List<TianjinSuperviseSessionVO> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(consultSessions)) {
            // mysql会话ID列表
            List<Long> sessionIds = consultSessions.stream().map(ses -> ses.getId()).collect(Collectors.toList());
            List<DrMessageConsultOrder> consultOrders =
                messageConsultOrderRepository.findByConsultSessionIdIn(sessionIds);
            Map<Long, DrMessageConsultOrder> consultOrderMap =
                consultOrders.stream().collect(Collectors.toMap(DrMessageConsultOrder::getConsultSessionId, e -> e));
            // 医生ID列表
            List<Long> doctorIds =
                consultSessions.stream().map(session -> session.getDoctorId()).collect(Collectors.toList());
            List<Licence> licenceList =
                licenceRepository.findByTypeAndDoctorIdIn(Licence.DOCTOR_LICENCE_TYPE_IDCARD, doctorIds);
            Map<Long, String> licenceMap =
                licenceList.stream().collect(Collectors.toMap(Licence::getDoctorId, Licence::getNumber, (a, b) -> b));

            // mongo会话详情集合
            List<String> sessionIdList =
                consultSessions.stream().map(ConsultSession::getSessionId).collect(Collectors.toList());
            List<SessionDetailBO> sessionDetailList =
                imFeginClient.sessionDetailList(CollectionUtil.join(sessionIdList, ","));
            Map<String, SessionDetailBO> sessionDetailMap =
                sessionDetailList.stream().collect(Collectors.toMap(SessionDetailBO::getSessionId, s -> s));

            // 就诊人
            List<Long> inquirerIds =
                consultSessions.stream().map(ConsultSession::getInquirerId).collect(Collectors.toList());
            List<PatientInquirerBO> patientInquirers = patientFeignClient.patientInquirerList(inquirerIds);
            Map<Long, PatientInquirerBO> inquirerMap =
                patientInquirers.stream().collect(Collectors.toMap(PatientInquirerBO::getInquirerId, i -> i));

            // 患者信息
            Set<Long> patientIds =
                consultSessions.stream().map(ConsultSession::getPatientId).collect(Collectors.toSet());
            List<Patient> patients = patientRepository.findByIdIn(patientIds);
            Map<Long, Patient> patientMap =
                patients.stream().collect(Collectors.toMap(Patient::getId, Function.identity()));

            // 查询处方诊断信息
            // Map<Long, Set<String>> recomDiagnosisMap =
            // recomFeginClient.recomDiagnosis(CollectionUtil.join(sessionIds, ","), null);
            consultSessions.forEach(session -> {
                Long patientId = session.getPatientId();
                Long doctorId = session.getDoctorId();
                PatientInquirerBO inquirer = inquirerMap.get(session.getInquirerId());
                Doctor doctor = doctorRepository.get(doctorId);
                Department department = departmentRepository.get(doctor.getDepartmentId());
                DrMessageConsultOrder consultOrder = consultOrderMap.get(session.getId());
                Patient patient = patientMap.get(session.getPatientId());
                TianjinSuperviseSessionVO vo = TianjinSuperviseSessionVO.builder().sessionId(session.getSessionId())
                    .departmentId(department.getId()).departmentName(department.getName()).doctorId(doctorId)
                    .doctorIdCard(licenceMap.get(doctorId)).doctorName(doctor.getName()).patientId(patientId)
                    .patientName(inquirer.getName()).patientGender(inquirer.getGender())
                    .patientAge(inquirer.getAgeYear()).patientIdCardNo(inquirer.getIdCard())
                    .patientPhone(patient.getPhone()).guardianIdCard(inquirer.getGuardianIdCard())
                    .guardianName(inquirer.getGuardianName())
                    .consultType(SuperviseConstant.Tianjin.CONSULT_TYPE_GRAPHIC)
                    .consultAttribute(SuperviseConstant.Tianjin.CONSULT_ATTRIBUTE_TREATMENT)
                    .startTime(session.getStartTime()).serviceEndTime(session.getEndTime())
                    .hasReply(SuperviseConstant.Tianjin.HAS_REPLY_REPLIED)
                    .payChannel(SuperviseConstant.Tianjin.PAY_CHANNEL_WECHAT).price(0).build();

                // 如果会话状态为未回复，设置咨询拒绝/取消参数
                if (session.getSessionStatus() == ConsultSession.SESSION_STATUS_UNANSWERED) {
                    vo.setHasReply(SuperviseConstant.Tianjin.HAS_REPLY_UNANSWERED);
                    vo.setRefuseTime(session.getEndTime());
                    vo.setRefuseType(SuperviseConstant.Tianjin.REFUSE_TYPE_TIMEOUT_CANCEL);
                }
                // 患者病情主诉信息
                SessionDetailBO sessionDetailBO = sessionDetailMap.get(session.getSessionId());
                String diseasesContent =
                    getDiseasesContent(sessionDetailBO.getRecordId(), sessionDetailBO.getSpecificMessageType());
                vo.setDiseasesContent(diseasesContent);

                // 处方诊断信息
                // Set<String> diagnosis = recomDiagnosisMap.get(session.getId());
                // if (CollectionUtil.isNotEmpty(diagnosis)) {
                // vo.setIsRecom(true);
                // vo.setDiagnosis(diagnosis);
                // }
                if (null != consultOrder) {
                    // 问诊价格
                    vo.setPrice(consultOrder.getPrice());
                }
                list.add(vo);
            });
        }
        return list;
    }

    /**
     * 获取主诉信息
     *
     * @param recordId
     *            记录id
     * @param type
     *            类型 1病例 2病情
     */
    public String getDiseasesContent(String recordId, Integer type) {
        if (StringUtils.isEmpty(recordId)) {
            return "";
        }
        InquireCaseBO caseBO;
        if (type == 1) {
            caseBO = emrFeignClient.getCase(recordId);
        } else {
            caseBO = emrFeignClient.getDisease(recordId);
        }
        return caseBO.getDescription();
    }

    @Override
    public List<TianjinSuperviseSessionVO> tianjinVideoConsult(String start, String end) throws BusinessException {
        // 视频问诊业务数据
        SuperviseVideoBO superviseVideo = videoConsultFeignClient.getVideoSuperviseInfo(start, end);
        List<TianjinSuperviseSessionVO> result = generateTianjinSuperviseVideoSession(superviseVideo);
        return result;
    }

    public List<TianjinSuperviseSessionVO> generateTianjinSuperviseVideoSession(SuperviseVideoBO superviseVideo)
        throws BusinessException {
        List<TianjinSuperviseSessionVO> videoData = new ArrayList<>();
        List<SuperviseVideoInfoBO> videoInfos = superviseVideo.getVideos();
        if (CollectionUtils.isEmpty(videoInfos)) {
            return videoData;
        }
        // 医生ID列表
        List<Long> doctorIds =
            videoInfos.stream().map(videoConsult -> videoConsult.getDoctorId()).collect(Collectors.toList());
        List<Licence> licenceList =
            licenceRepository.findByTypeAndDoctorIdIn(Licence.DOCTOR_LICENCE_TYPE_IDCARD, doctorIds);
        Map<Long, String> licenceMap =
            licenceList.stream().collect(Collectors.toMap(Licence::getDoctorId, Licence::getNumber, (a, b) -> b));
        // 就诊人
        List<Long> inquirerIds =
            videoInfos.stream().map(SuperviseVideoInfoBO::getInquirerId).collect(Collectors.toList());
        List<PatientInquirerBO> patientInquirers = patientFeignClient.patientInquirerList(inquirerIds);
        Map<Long, PatientInquirerBO> inquirerMap =
            patientInquirers.stream().collect(Collectors.toMap(PatientInquirerBO::getInquirerId, i -> i));
        // 查询处方诊断信息
        List<List<Long>> recomIds =
            videoInfos.stream().map(SuperviseVideoInfoBO::getRecomIds).collect(Collectors.toList());
        Map<Long, Set<String>> recomDiagnosisMap =
            recomFeginClient.recomDiagnosis(null, CollectionUtil.join(recomIds, ","));
        // 患者信息
        Set<Long> patientIds = videoInfos.stream().map(SuperviseVideoInfoBO::getPatientId).collect(Collectors.toSet());
        List<Patient> patients = patientRepository.findByIdIn(patientIds);
        Map<Long, Patient> patientMap =
            patients.stream().collect(Collectors.toMap(Patient::getId, Function.identity()));
        // 只取已取消或者已完成的咨询
        videoInfos.stream().filter(v -> v.getConsultStatus() == DrVideoConsult.VIDEO_CONSULT_STATUS_CANCEL
            || v.getConsultStatus() == DrVideoConsult.VIDEO_CONSULT_STATUS_COMPLETE).forEach(videoConsult -> {
                Long patientId = videoConsult.getPatientId();
                Long doctorId = videoConsult.getDoctorId();
                PatientInquirerBO inquirer = inquirerMap.get(videoConsult.getInquirerId());
                Doctor doctor = doctorRepository.get(doctorId);
                Department department = departmentRepository.get(doctor.getDepartmentId());
                Patient patient = patientMap.get(videoConsult.getPatientId());
                TianjinSuperviseSessionVO vo = TianjinSuperviseSessionVO.builder().sessionId(videoConsult.getOrderSn())
                    .departmentId(department.getId()).departmentName(department.getName()).doctorId(doctorId)
                    .doctorIdCard(licenceMap.get(doctorId)).doctorName(doctor.getName()).patientId(patientId)
                    .patientName(inquirer.getName()).patientGender(inquirer.getGender())
                    .patientAge(inquirer.getAgeYear()).patientIdCardNo(inquirer.getIdCard())
                    .patientPhone(patient.getPhone()).guardianIdCard(inquirer.getGuardianIdCard())
                    .guardianName(inquirer.getGuardianName()).consultType(SuperviseConstant.Tianjin.CONSULT_TYPE_VIDEO)
                    .consultAttribute(SuperviseConstant.Tianjin.CONSULT_ATTRIBUTE_TREATMENT)
                    .startTime(videoConsult.getCreatedAt()).hasReply(SuperviseConstant.Tianjin.HAS_REPLY_REPLIED)
                    .payChannel(SuperviseConstant.Tianjin.PAY_CHANNEL_WECHAT).processDataURL(videoConsult.getVideoUrl())
                    .price(videoConsult.getPrice()).diseasesContent(videoConsult.getConditionDesc()).build();
                // 判断如果咨询状态为已取消，设置咨询拒绝/取消参数
                if (videoConsult.getConsultStatus() == DrVideoConsult.VIDEO_CONSULT_STATUS_CANCEL) {
                    long l = DateUtil.compareDate(videoConsult.getChangedAt(), videoConsult.getCreatedAt());
                    vo.setRefuseTime(videoConsult.getChangedAt());
                    vo.setRefuseReason(videoConsult.getRefusalReason());
                    vo.setRefuseType(SuperviseConstant.Tianjin.REFUSE_TYPE_INITIATIVE);
                    // 如果结束时间和开始时间相差一小时，则代表是超时自动取消
                    if (l >= 60 * 60 * 1000) {
                        vo.setRefuseType(SuperviseConstant.Tianjin.REFUSE_TYPE_TIMEOUT_CANCEL);
                    }
                } else if (videoConsult.getConsultStatus() == DrVideoConsult.VIDEO_CONSULT_STATUS_COMPLETE) {
                    // 如果咨询状态为已完成，设置结束时间
                    vo.setServiceEndTime(videoConsult.getChangedAt());
                }
                // 患者病情主诉信息
                // String recordId = videoConsult.getDiseaseId() == null ? videoConsult.getMedicalRecordId()
                // : videoConsult.getDiseaseId();
                // Integer recordType = videoConsult.getDiseaseId() == null ? 1 : 2;
                // String diseasesContent = getDiseasesContent(recordId, recordType);
                // vo.setDiseasesContent(diseasesContent);

                // 线下诊断
                if(StringUtils.isNotBlank(videoConsult.getOfflineDiagnosis())){
                    vo.setOriginalDiagnosis(new HashSet<>(Arrays.asList(videoConsult.getOfflineDiagnosis().split(","))));
                }
                // 处方诊断信息
                List<Long> recomIdsItem = videoConsult.getRecomIds();
                if (StringUtils.isNotEmpty(videoConsult.getDiagnosis())) {
                    vo.setDiagnosis(new HashSet<>(Arrays.asList(videoConsult.getDiagnosis().split(","))));
                } else if (CollectionUtil.isNotEmpty(recomIdsItem)) {
                    Set<String> diagnosisSet = new HashSet();
                    recomIdsItem.stream().forEach(rId -> {
                        Set<String> diagnosis = recomDiagnosisMap.get(rId);
                        if (CollectionUtil.isNotEmpty(diagnosis)) {
                            diagnosisSet.addAll(diagnosis);
                        }
                    });
                    vo.setDiagnosis(diagnosisSet);
                }
                // 如果视频问诊为已完成并且没有诊断信息，则不进行同步
                if (videoConsult.getConsultStatus() == DrVideoConsult.VIDEO_CONSULT_STATUS_COMPLETE
                    && CollectionUtils.isEmpty(vo.getDiagnosis())) {
                    return;
                }

                videoData.add(vo);
            });
        return videoData;
    }

    @Override
    public List<SuperviseConsultCommentVO> consultComment(Date startDate, Date endDate) {
        List<DrConsultComment> consultComments = consultCommentRepository.findByCreatedAtBetween(startDate, endDate);
        if (CollectionUtil.isEmpty(consultComments)) {
            return new ArrayList<>();
        }
        // 医生信息
        Set<Long> doctorIds = consultComments.stream().map(DrConsultComment::getDoctorId).collect(Collectors.toSet());
        List<Doctor> doctors = doctorRepository.findByIdIn(doctorIds);
        Map<Long, Doctor> doctorMap = doctors.stream().collect(Collectors.toMap(Doctor::getId, d -> d));

        // 患者信息
        Set<Long> patientIds = consultComments.stream().map(DrConsultComment::getPatientId).collect(Collectors.toSet());
        List<Patient> patients = patientRepository.findByIdIn(patientIds);
        Map<Long, Patient> patientMap = patients.stream().collect(Collectors.toMap(Patient::getId, p -> p));

        // 医生身份证信息
        List<Licence> licenceList =
            licenceRepository.findByTypeAndDoctorIdIn(Licence.DOCTOR_LICENCE_TYPE_IDCARD, doctorIds);
        Map<Long, String> licenceMap =
            licenceList.stream().collect(Collectors.toMap(Licence::getDoctorId, Licence::getNumber, (a, b) -> b));

        // 图文咨询信息
        List<Long> sessionIds = consultComments.stream().filter(comment -> comment.getConsultType() == 1)
            .map(DrConsultComment::getConsultSessionId).collect(Collectors.toList());
        Map<Long, String> sessionMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(sessionIds)) {
            List<ConsultSession> consultSessions = consultSessionRepository.findAllByIdIn(sessionIds);
            sessionMap =
                consultSessions.stream().collect(Collectors.toMap(ConsultSession::getId, ConsultSession::getSessionId));
        }

        // 视频咨询信息
        Set<Long> videoConsultSessionIds = consultComments.stream().filter(comment -> comment.getConsultType() == 2)
            .map(DrConsultComment::getConsultSessionId).collect(Collectors.toSet());
        Map<Long, String> videoConsultMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(videoConsultSessionIds)) {
            List<VideoConsultBO> videoConsultBOS = videoConsultFeignClient.getVideoConsult(videoConsultSessionIds);
            videoConsultMap =
                videoConsultBOS.stream().collect(Collectors.toMap(VideoConsultBO::getId, VideoConsultBO::getOrderSn));
        }

        List<SuperviseConsultCommentVO> result = new ArrayList<>();
        for (DrConsultComment consultComment : consultComments) {
            Doctor doctor = doctorMap.get(consultComment.getDoctorId());
            Patient patient = patientMap.get(consultComment.getPatientId());
            Department department = departmentRepository.get(doctor.getDepartmentId());
            // 获取不同咨询类型的sessionId
            String sessionId;
            if (consultComment.getConsultType() == 1) {
                sessionId = sessionMap.get(consultComment.getConsultSessionId());
            } else {
                sessionId = videoConsultMap.get(consultComment.getConsultSessionId());
            }
            result.add(SuperviseConsultCommentVO.builder().id(consultComment.getId()).sessionId(sessionId)
                .consultType(consultComment.getConsultType()).departmentId(doctor.getDepartmentId())
                .departmentName(department.getName()).doctorId(doctor.getId())
                .doctorIdCard(licenceMap.get(doctor.getId())).doctorName(doctor.getName())
                .starLevel(consultComment.getStarLevel()).commentContent(consultComment.getCommentContent())
                .patientId(patient.getId()).patientName(patient.getName()).createdAt(consultComment.getCreatedAt())
                .build());
        }
        return result;
    }
}
